#include "head.h"

int num = 0; // 记录用户输入错误次数
// 数据操作
void user_data_file_print(u_list *list, const char *file_name, const char *mode) //  向文件写入用户信息
{
    // 安全判断
    IsEmpty_link_u_List(list);
    // 打开文件
    FILE *fp = fopen(file_name, mode);
    // 安全判断
    if (NULL == fp)
    {
        ERRLOG("文件打开失败");
        return;
    }
    // 移动光标到开头
    fseek(fp, 0, SEEK_SET);
    // 遍历写入
    u_node *ptr = list->next;
    do
    {
        fprintf(fp, "%s\t\t%s\t\t%s\t\t%d\t\t%s\t\t%d\t\t%d\t\t%d\n",
                ptr->data.name, ptr->data.passwd, ptr->data.sex, ptr->data.level, ptr->data.phone, ptr->data.value,ptr->data.total_payment,ptr->data.tickets);
        ptr = ptr->next;
    } while (NULL != ptr);
    fflush(fp); // 刷新文件
    fclose(fp);
}
void user_data_file_scanf(u_list *list, const char *file_name) //  向文件读取用户信息
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("双向循环链表 为 NULL");
        return;
    }

    FILE *fp = fopen(file_name, "r+");
    if (NULL == fp)
    {
        ERRLOG("文件打开失败!");
        return;
    }
    // 移动光标
    fseek(fp, 0, SEEK_SET);

    // 清空链表
    if (NULL != list->next)
    {
        clear_u_list(list);
    }

    user_data data;
    int line_num = 0;

    // 检测文件行数
    line_num = count_line(file_name);

    fflush(fp); // 刷新文件

    // 移动光标到开头
    fseek(fp, 0, SEEK_SET);

    for (int i = 0; i < line_num; i++)
    {
        fscanf(fp, "%s\t\t%s\t\t%s\t\t%d\t\t%s\t\t%d\t\t%d\t\t%d\n",
               data.name, data.passwd, data.sex, &data.level, data.phone, &data.value,&data.total_payment,&data.tickets);
        tail_insert_u_node(list, data); // 读一行数据插入一行数据
    }
    fflush(fp); // 刷新文件
    fclose(fp);
}

// 根据用户等级属性，写入到不同的文件中
void user_fprint_by_level(u_list *user, const char *mode)
{
    // 根据用户等级码，写入到对应的文件
    switch (user->next->data.level)
    {
    case 1:
        user_data_file_print(user, ADMIN_FILE, mode); // 管理员账户信息文件
        break;
    case 2:
        user_data_file_print(user, REGULAR_FILE, mode); // 普通用户信息文件
        break;
    case 3:
        user_data_file_print(user, SILVER_FILE, mode); // 银卡会员信息文件 (9折)
        break;
    case 4:
        user_data_file_print(user, GOLD_FILE, mode); // 金卡会员信息文件 (8折)
        break;
    case 5:
        user_data_file_print(user, PLATINUM_FILE, mode); // 白金会员信息文件 (7折)
        break;
    }
}

// 根据用户等级属性，从文件中读入不同的用户数据
u_list *user_fscanf_by_level(user_data data)
{
    // 从文件中读取数据
    FlightSystem Flight_sys = Sys_init();
    // 根据用户等级码，写入到对应的文件
    switch (data.level)
    {
    case 1:
        // 管理员账户信息文件
        return Flight_sys.ADMIN_USER;
        break;
    case 2:
        // 普通用户信息文件
        return Flight_sys.REGULAR_USER;
        break;
    case 3:
        // 银卡会员信息文件 (9折)
        return Flight_sys.SILVER_USER;
        break;
    case 4:
        // 金卡会员信息文件 (8折)
        return Flight_sys.GOLD_USER;
        break;
    case 5:
        // 白金会员信息文件 (7折)
        return Flight_sys.PLATINUM_USER;
        break;
    }
    return NULL;
}


// 用户登录
user_data u_login(u_list *list)
{
    // 安全判断
    IsEmpty_link_u_List(list);
    // 接受用户输入的账号、密码信息
    user_data data;

    // 开始登录
    while (1)
    {

        // 清屏
        system("clear");
        text_center("请输入用户:", GREEN);
        scanf("%s", data.name);

        text_center("请输入密码:", GREEN);
        scanf("%s", data.passwd);

        u_node *ptr = list->next; // 遍历用户表

        for (size_t i = 0; NULL != ptr; i++)
        {
            // 判断用户名是否输入正确
            if (strcmp(data.name, ptr->data.name) == 0)
            {
                // 判断密码是否输入正确
                if (strcmp(data.passwd, ptr->data.passwd) == 0)
                {
                    data = ptr->data;
                    plane_nc();     //大飞机
                    return data;
                }
            }
            ptr = ptr->next;
        }
        // 错误提醒,不能在for循环里面，否则遍历不到
        puts("");
        text_center("       用户名或密码输入错误!", RED);
        puts("");
        play_bgm(ERO);
        num++;
        sleep(1);
        // 停止并释放音乐
        Mix_HaltMusic();
        Mix_CloseAudio();
        // 限制用户输入次数
        juge_in_times(&num);
    }
}

// 用户注册
user_data u_register()
{
    // 接收用户输入的信息
    user_data data;
    char name[16];
    char password[16];
    char sex[16];
    char phone[16];
    // 初始化用户链表
    u_list *u = init_u_list();
    // 从文件中读取普通用户信息
    user_data_file_scanf(u, REGULAR_FILE); // 普通用户信息文件

    // 判断用户名是否重复
    while (1)
    {
        system("clear");
        text_center("姓名:", GREEN);
        scanf("%s", name);
        strcpy(data.name, name);

        // 判断用户名是否重复
        if (1 == is_onlyname(name))
        {
           break;
        }
    }

    text_center("密码:", GREEN);
    scanf("%s", password);
    strcpy(data.passwd, password);

    text_center("性别:", GREEN);
    scanf("%s", sex);
    strcpy(data.sex, sex);

    text_center("手机:", GREEN);
    scanf("%s", phone);
    strcpy(data.phone, phone);

    // 默认注册用户等级为普通用户
    data.level = 2;
    // 初始余额为0
    data.value = 0;
    // 初始累计充值余额为0
    data.total_payment = 0;
    // 初始化票数为0
    data.tickets = 0;
    // 尾插写入到用户表
    Tail_u_node(u, data);
    // 写入到文件
    user_data_file_print(u, REGULAR_FILE,"w+");

    play_bgm(REG);
    puts("");
    text_center("注册成功!请重新登录!\n", YELLOW);
    puts("");
    //显示注册信息
    // print_one_udata(data);
    sleep(1);
    // 停止并释放音乐
    Mix_HaltMusic();
    Mix_CloseAudio();
    return data;
}

// 根据手机找回密码
u_node *find_u_node_phone(u_list *list)
{
    // 初始化、声明要放在循环外面
    char phone_num[16];
    // 安全判断
    IsEmpty_link_u_List(list);
    u_node *p = list->next;
    while (1)
    {
        text_center("请输入你注册的手机号:", GREEN);
        scanf("%s", phone_num);
        p = list->next;

        //判断用户输入的密码是否正确
        while (strcmp(p->data.phone, phone_num))
        {
            p = p->next;
            if (p == NULL)
            {
                text_center("你输入的手机号码有误!\n", RED);
                break;
            }
        }
        if (NULL != p)
        {
            puts("");
            text_center("你的登录密码为:", GREEN);
            printf("%s\n", p->data.passwd);
            sleep(3);
            return p;
        }   
    }
}

//修改密码
void modify_passwd(user_data data)
{
    system("clear");
    char old[16]; // 接收旧密码
    char new[16]; // 接受新密码
    // 从文件中读取数据
    u_list *u = init_u_list();
    u = user_fscanf_by_level(data);
    // 安全判断
    IsEmpty_link_u_List(u);
    u_node *p = u->next;
    while (strcmp(p->data.name, data.name))
    {
        if (p == NULL)
        {
            text_center("抱歉,查无此人!\n", RED);
            return ;
        }
        p = p->next;  
    }
    while (1)
    {
        // 安全判断
        text_center("请输入旧密码:", GREEN);
        scanf("%s", old);
        while (1)
        {
            //判断输入的密码是否正确
            if (strcmp(p->data.passwd, old))
            {
                text_center("密码错误,请重新输入!\n", RED);
                play_bgm(ERO);
                sleep(1);
                // 停止并释放音乐
                Mix_HaltMusic();
                Mix_CloseAudio();
                break;
            }
            else
            {
                text_center("请输入新密码:", GREEN);
                scanf("%s", new);
                strcpy(p->data.passwd, new);
                puts("");
                text_center("密码修改成功!", YELLOW);
                //写入到文件
                user_fprint_by_level(u,"w+");
                puts("");
                return;
            }
        }
    }
   
}


//余额充值
void add_money(user_data data)
{
    system("clear");
    int money=0;         // 充值的大小
    char payment[16];    // 支付密码
    // 从文件中读取数据
    u_list *u = init_u_list();
    u = user_fscanf_by_level(data);
    // 安全判断
    IsEmpty_link_u_List(u);
    u_node *p = u->next;
    //查找对应的结点
    while (strcmp(p->data.name, data.name))
    {
        if (p == NULL)
        {
            text_center("抱歉,查无此人!\n", RED);
            return;
        }
        p = p->next;
    }

    // 显示当前余额
    text_center("当前余额:", GREEN);
    printf("%d元\n", data.value);
    puts("");
    while (1)
    {
        text_center("请输入充值金额:", GREEN);
        scanf("%d", &money);
        // 金额必须要大于0
        if (money < 0)
        {
            puts("");
            text_center("充值金额必须大于0!\n", RED);
            continue;
        }
        break;
    }

    while (1)
    {
       
        // 安全判断
        text_center("请输入支付密码:", GREEN);
        scanf("%s", payment);
        while (1)
        {
            // 判断输入的支付密码是否正确(支付密码和登录密码相同)
            if (strcmp(p->data.passwd, payment))
            {
                text_center("密码错误,请重新输入!\n", RED);
                play_bgm(ERO);
                sleep(1);
                // 停止并释放音乐
                Mix_HaltMusic();
                Mix_CloseAudio();
                break;
            }
            else
            {
                //修改总金额
                data.total_payment = data.total_payment + money;
                //修改当前余额
                data.value = data.value + money;

                play_bgm(ADD);
                puts("");
                text_center("充值成功!\n", YELLOW);
                text_center("当前余额:", YELLOW);
                sleep(1);
                // 停止并释放音乐
                Mix_HaltMusic();
                Mix_CloseAudio();

                printf("%d元\n", data.value);
                sleep(1.5);
                u_list *v = init_u_list();
                // 当累计充值金额达到10000自动升级为银卡会员
                if (data.total_payment>=10000 && data.total_payment<15000 &&data.level!=3)
                {
                    play_bgm(UP);
                    printf("                                                   %s恭喜你成为尊贵的银卡会员!\n",WHITE);
                    sleep(1);
                    // 停止并释放音乐
                    Mix_HaltMusic();
                    Mix_CloseAudio();
                    data.level = 3;
                    // 找到对应等级的用户信息表
                    v = user_fscanf_by_level(data);
                    // 尾插到升级后的用户数据表里面
                    tail_insert_u_node(v, data);
                    // 删除原有链表用户的数据
                    delete_u_node_byname(u, data.name);
                    return;
                }
                // 当累计充值金额达到15000自动升级为金卡会员
                else if (data.total_payment >= 15000 && data.total_payment < 20000 && data.level != 4)
                {
                    play_bgm(UP);
                    printf("                                                   %s恭喜你成为尊贵的金卡会员!\n",YELLOW);
                    sleep(1);
                     // 停止并释放音乐
                    Mix_HaltMusic();
                    Mix_CloseAudio();
                    data.level = 4;
                    // 找到对应等级的用户信息表
                    v = user_fscanf_by_level(data);
                    // 尾插到升级后的用户数据表里面
                    tail_insert_u_node(v, data);
                    // 删除原有链表用户的数据
                    delete_u_node_byname(u, data.name);
                    return;
                }
                // 当累计充值金额达到20000自动升级为白金会员
                else if (data.total_payment >= 20000 && data.level != 5)
                {
                    play_bgm(UP);
                    printf("                                                   %s恭喜你成为尊贵的白金会员!\n", BLUE);
                    sleep(1);
                    // 停止并释放音乐
                    Mix_HaltMusic();
                    Mix_CloseAudio();
                    data.level = 5;
                    // 找到对应等级的用户信息表
                    v = user_fscanf_by_level(data);
                    // 尾插到升级后的用户数据表里面
                    tail_insert_u_node(v, data);
                    // 删除原有链表用户的数据
                    delete_u_node_byname(u, data.name);
                    return;
                }
                // 如果用户等级没有修改则不需要删除原有的信息
                // 写入到原来的等级表里面去
                // 修改当前余额
                p->data.value = data.value;
                // 修改总金额
                p->data.total_payment = data.total_payment;
                user_fprint_by_level(u,"w+");
                return;
            }
        }
    }
}

// 个人中心
void user_center(user_data data)
{
    //清屏
    system("clear");
    // 从文件中读取数据
    u_list *u = init_u_list();
    u = user_fscanf_by_level(data);
    // 安全判断
    IsEmpty_link_u_List(u);
    u_node *p = u->next;
    while (strcmp(p->data.name, data.name))
    {
        if (p == NULL)
        {
            text_center("抱歉,查无此人!\n", RED);
            return;
        }
        p = p->next;
    }
    //用户选择
    int select = 0;
    puts("");
    text_center("1--------用户:",GREEN);
    printf("%s\n",p->data.name);
    text_center("2--------密码:", GREEN);
    printf("%s\n", p->data.passwd);
    text_center("3--------性别:", GREEN);
    printf("%s\n", p->data.sex);
    text_center("4--------等级:", GREEN);
    printf("%d\n", p->data.level);
    text_center("5--------余额:", GREEN);
    printf("%d\n", p->data.value);
    text_center("       6--------累计充值:", GREEN);
    printf("%d\n", p->data.total_payment);
    text_center("       7--------手机号码:", GREEN);
    printf("%s\n", p->data.phone);
    puts("");

    text_center("有效数字1,2,3,7\n", YELLOW);
    text_center("请选择你要修改的的信息:",YELLOW);
    scanf("%d",&select);

    switch (select)
    {
    case 1:
        //用户名
        text_center("请输入新的用户名:", YELLOW);
        scanf("%s", p->data.name);
        printf("%s\n",p->data.name);
        //写入到文件
        user_fprint_by_level(u, "w+");
        break;
    case 2:
        // 密码
        modify_passwd(data);
        break;
    case 3:
        // 性别
        text_center("请输入你的性别:", YELLOW);
        scanf("%s", p->data.sex);
        // 写入到文件
        user_fprint_by_level(u, "w+");
        break;
    case 7:
        // 手机号码
        text_center("请输入新的手机号码:", YELLOW);
        scanf("%s", p->data.phone);
        // 写入到文件
        user_fprint_by_level(u, "w+");
        break;
    default:
        puts("");
        //非法输入
        text_center("非法操作,没有权限修改!\n:", RED);
        break;
    }
    return;
}


// 购票
void buy_ticket(f_list *flight, Sql_list *ticket, user_data data)
{
    system("clear");
    char start_city[20];
    char arrive_city[20];
    int id = 0;
    //从文件中读取用户信息表
    u_list *u = init_u_list();
    u = user_fscanf_by_level(data);
    u_node *u_ptr = find_u_node_name(u,data.name);//找到用户对应表里面的指针
    while (1)
    {
        text_center("请输入你的飞行起点:", GREEN);
        scanf("%s", start_city);
        text_center("请输入你的飞行终点:", GREEN);
        scanf("%s", arrive_city);
       
        f_node *f = is_find_location(flight, start_city, arrive_city);
        // 判断输入的起始点是否正确
        if (NULL == f)
        {
            text_center("抱歉,暂无这两地之间的航班,请重新输入!\n", RED);
            sleep(2);
            return;
        }
        // 根据起始地查找航班
        find_double_node_location(flight, start_city, arrive_city);
        // 根据班次购票机票
        puts("");
        text_center("请选择你要购买的班次:", GREEN);
        scanf(" %d", &id);
        //判断是否重复购买
        if (!is_buy_ticket(ticket, id, data.name))
        {
            sleep(1);
            return;
        }
        //找到对应的航班结点
        f_node *f_ptr = find_double_node_id(flight, &id);

        // 余额判断
        if (u_ptr->data.value < f_ptr->data.value)
        {
            text_center("余额不足请充值!\n", RED);
            return;
        }
        //  是否售罄
        if (f_ptr->data.leftbuyersa==0)
        {
            text_center("该班次机票已售罄!\n",RED);
            sleep(1);
            return;
        }
        //  是否起飞
        if ('y' == f_ptr->data.whetherfly)
        {
            text_center("该班次航班已经起飞!\n", RED);
            sleep(2);
            return;
        }

        // 生成用户订单信息并写入到文件中
        ticket_data t_data;
        // 初始化随机数生成器的种子
        srand(time(NULL));
        // 生成一个0或1的随机数
        int num = rand() % 2;
        // 随机分配机舱
        char *cabinType = (num == 0) ? "经济舱" : "头等舱";
        strcpy(t_data.cabin, cabinType);
        //经济舱优惠一点
        if (num==0)
        {
            t_data.value = f_ptr->data.value*0.8;
        }
        // 将航班信息写入到用户订单信息中
        t_data.id = f_ptr->data.id;
        t_data.value = f_ptr->data.value ;
        t_data.starttime[0] = f_ptr->data.starttime[0] ;
        t_data.starttime[1] = f_ptr->data.starttime[1];
        t_data.arrivetime[0] = f_ptr->data.arrivetime[0];
        t_data.arrivetime[1] = f_ptr->data.arrivetime[1];
        strcpy(t_data.flighttype, f_ptr->data.flighttype);
        strcpy(t_data.startcity, f_ptr->data.startcity);
        strcpy(t_data.arrivecity, f_ptr->data.arrivecity);
        strcpy(t_data.flytime, f_ptr->data.flytime);
        strcpy(t_data.name, data.name);
        getCurrentTimeStr(t_data.order_time,sizeof(t_data.order_time));
    
        //根据用户等级不同享受不同的优惠价格
        switch (data.level)
        {
        case 3:
            //银卡用户-0.9
            u_ptr->data.value = data.value - (t_data.value)* SILVER_DISCOUNT;
            break;
        case 4:
            //金卡用户-0.8
            u_ptr->data.value = data.value - (t_data.value) * GOLD_DISCOUNT;
            break;
        case 5:
            //白金用户-0.7
            u_ptr->data.value = data.value - (t_data.value) * PLATINUM_DISCOUNT;
            break;
        default:
            u_ptr->data.value = data.value - t_data.value;
            break;
        }
        //票数加1
        u_ptr->data.tickets = u_ptr->data.tickets+1;
        // 修改剩余座位
        f_ptr->data.leftbuyersa = f_ptr->data.leftbuyersa - 1;
        // 确认订单信息
        int select = 0;
        text_center("请确认订单信息\n", GREEN);
        printf("班次    机型            起点站         终点站           起飞时间        到达时间        飞行时间       票价           载客量         剩余座位    是否起飞\n");
        printf("--------------------------------------------------------------------------------------------------\n");
        print_flight_1(f_ptr);
        puts("");
        text_center("1——确认无误\t2——重新购买:", GREEN);
        scanf(" %d", &select);
       
        if (1 == select)
        {
            // 修改航班班次剩余座位
            flight_data_file_print(flight);
            // 将用户信息保存到文件
            user_fprint_by_level(u, "w+");
            // 写入到用户订单信息表
            tail_insert_sqlist(ticket, t_data);
            text_center("购票成功!\n",YELLOW);
            sleep(1);
            return;
        }
        else
        {
            continue;
        }
    }
    return;
}

// 退票
void refund_ticket(Sql_list *ticket, f_list *flight,user_data data)
{
    // 从文件中读取用户信息表
    u_list *u = init_u_list();
    u = user_fscanf_by_level(data);
    u_node *u_p = find_u_node_name(u, data.name); // 找到用户表里面的指针
    // 按名字查并打印你的购票信息
    printf("班次    机型            起点站         终点站           起飞时间        到达时间        飞行时间       票价           载客量         剩余座位    是否起飞\n");
    printf("--------------------------------------------------------------------------------------------------\n");
    user_order_tickets(ticket,data.name);
    text_center("请选择你要退订的机票:",GREEN);
    int id = 0;
    scanf(" %d",&id);
    //根据班次查找对应的机票信息
    f_node *p= find_double_node_id(flight,&id);
    // 修改剩余座位
    p->data.leftbuyersa = p->data.leftbuyersa +1;
    // 用户票数减1
    u_p->data.tickets=u_p->data.tickets-1;
    // 修改航班班次剩余座位
    flight_data_file_print(flight);
    // 根据用户等级不同退票
    switch (data.level)
    {
    case 3:
        // 银卡用户-0.9
        u_p->data.value = data.value + p->data.value * SILVER_DISCOUNT;
        break;
    case 4:
        // 金卡用户-0.8
        u_p->data.value = data.value + p->data.value * GOLD_DISCOUNT;
        break;
    case 5:
        // 白金用户-0.7
        u_p->data.value = data.value + p->data.value * PLATINUM_DISCOUNT;
        break;
    default:
        u_p->data.value = data.value + p->data.value;
        break;
    }
    //保存到用户信息表中
    user_fprint_by_level(u,"w+");
    // 按航班班次和名字删除
    pos_del_sqlist(ticket,id, data.name);
    text_center("退票成功!\n",YELLOW);
    sleep(1);
    return;
}

